package cn.iocoder.yudao.module.promotion.gift.service.admin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreQueryWrapper;
import cn.iocoder.yudao.framework.business.basic.pojo.vo.ShopSimpleVO;
import cn.iocoder.yudao.framework.business.basic.service.impl.MerchantScopeService;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.region.RegionUtils;
import cn.iocoder.yudao.framework.region.enums.RegionDataSet;
import cn.iocoder.yudao.module.api.product.sku.ProductSkuApi;
import cn.iocoder.yudao.module.api.product.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.api.product.spu.ProductSpuApi;
import cn.iocoder.yudao.module.api.product.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.api.promotion.coupon.CouponTemplateApi;
import cn.iocoder.yudao.module.api.promotion.coupon.dto.CouponTemplateRespDTO;
import cn.iocoder.yudao.module.api.promotion.gift.dto.GiftActivityVO;
import cn.iocoder.yudao.module.api.promotion.gift.enums.GiftGiveType;
import cn.iocoder.yudao.module.api.shop.category.eums.ShopCategoryCodeEnum;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.promotion.gift.convert.GiftActivityConvert;
import cn.iocoder.yudao.module.promotion.gift.dao.GiftActivityMapper;
import cn.iocoder.yudao.module.promotion.gift.pojo.dto.AdminGiftActivityQueryDTO;
import cn.iocoder.yudao.module.promotion.gift.pojo.dto.AdminGiftActivitySaveDTO;
import cn.iocoder.yudao.module.promotion.gift.pojo.po.GiftActivity;
import jakarta.annotation.Nonnull;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 *  这里是文件说明
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/01/13
 */
@Service
@Validated
public class GiftActivityServiceImpl extends MerchantScopeService<GiftActivity, GiftActivityVO, AdminGiftActivityQueryDTO> implements GiftActivityService {
    @Resource
    private GiftActivityMapper giftActivityMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ShopInfoApi shopInfoApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ProductSkuApi productSkuApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ProductSpuApi productSpuApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private CouponTemplateApi couponTemplateApi;

    @Override
    public GiftActivityMapper getInjectedMapper() {
        return giftActivityMapper;
    }

    @Override
    public GiftActivity convertToEntity(AdminGiftActivitySaveDTO param) {
        return GiftActivityConvert.INSTANCE.convert(param);
    }

    @Override
    public GiftActivityVO convertToViewObject(GiftActivity entity) {
        return GiftActivityConvert.INSTANCE.convert(entity);
    }

    @Nonnull
    @Override
    protected CoreQueryWrapper<GiftActivity> buildQueryWrapper(AdminGiftActivityQueryDTO param) {
        CoreQueryWrapper<GiftActivity> wrapper = super.buildQueryWrapper(param);
        wrapper.eqIfPresent("type", param.getType());
        wrapper.inIfPresent("id", param.getIds());
        wrapper.eqIfPresent("shop_id", param.getShopId());
        if (param.getPartnerShopId() != null && param.getPartnerShopId() > 0) {
            wrapper.apply("FIND_IN_SET({0}, partner_shop_ids) > 0", param.getPartnerShopId());
        }
        wrapper.eqIfPresent("spu_id", param.getSpuId());
        wrapper.eqIfPresent("coupon_template_id", param.getCouponTemplateId());
        wrapper.likeIfPresent("name", param.getName());
        if (Boolean.TRUE.equals(param.getValid())) {
            LocalDateTime now = LocalDateTime.now();
            wrapper.geIfPresent("start_time", now);
            wrapper.ltIfPresent("end_time", now);
        } else if (Boolean.FALSE.equals(param.getValid())) {
            LocalDateTime now = LocalDateTime.now();
            wrapper.leIfPresent("end_time", now);
        }
        return wrapper;
    }


    @Override
    public Long create(AdminGiftActivitySaveDTO param) {
        GiftActivity entity;
        if (param.getSkuId() != null && param.getSkuId() > 0) {
            ProductSkuRespDTO skuRespDTO = productSkuApi.validateSku(param.getSkuId());
            ProductSpuRespDTO spuRespDTO = productSpuApi.validateSpu(skuRespDTO.getSpuId());
            entity = convertToEntity(param);
            entity.setId(null);
            entity.setSkuId(param.getSkuId());
            entity.setSpuId(skuRespDTO.getSpuId());
            entity.setShopId(skuRespDTO.getShopId());
            entity.setType(ShopCategoryCodeEnum.MALL.getCode().equals(spuRespDTO.getType()) ? GiftGiveType.ONLINE_PRODUCT.getValue() : GiftGiveType.OFFLINE_PRODUCT.getValue());
            entity.setName(spuRespDTO.getName());
            if (StrUtil.isEmpty(skuRespDTO.getPicUrl())) {
                entity.setPicUrl(spuRespDTO.getPicUrl());
            } else {
                entity.setPicUrl(skuRespDTO.getPicUrl());
            }
            entity.setOriginPrice(param.getOriginPrice());
            entity.setCostPrice(param.getCostPrice());
            entity.setStock(skuRespDTO.getStock());
            //entity.setUnit(spuRespDTO.getUnit());
        } else if (param.getCouponTemplateId() != null && param.getCouponTemplateId() > 0) {
            CouponTemplateRespDTO couponTemplateRespDTO = couponTemplateApi.validateTemplate(param.getCouponTemplateId());
            entity = convertToEntity(param);
            entity.setId(null);
            entity.setShopId(couponTemplateRespDTO.getShopId());
            entity.setType(GiftGiveType.COUPON_TEMPLATE.getValue());
            entity.setCouponTemplateId(couponTemplateRespDTO.getId());
            entity.setName(couponTemplateRespDTO.getName());
            entity.setOriginPrice(couponTemplateRespDTO.getDiscountPrice());
            entity.setCostPrice(0);
            entity.setStock(couponTemplateRespDTO.getTotalCount() == -1 ? 99999 : couponTemplateRespDTO.getTotalCount());
            entity.setTakeLimitCount(couponTemplateRespDTO.getTakeLimitCount() == -1 ? 99999 : couponTemplateRespDTO.getTakeLimitCount());
        } else {
            entity = convertToEntity(param);
            entity.setId(null);
            entity.setShopId(shopInfoApi.getShopIdByAdminUserId(getLoginUserId()));
            entity.setType(GiftGiveType.OFFLINE_PRODUCT.getValue());
            entity.setOriginPrice(param.getOriginPrice());
            entity.setCostPrice(param.getCostPrice());
        }
        if (StrUtil.isBlank(entity.getNote())) {
            entity.setNote("解释权归合作商家");
        }
        giftActivityMapper.insert(entity);
        return entity.getId();
    }

    @Override
    public boolean delete(Long id) {
        GiftActivity entity = validateExists(id);
        Assertions.isTrue(Boolean.TRUE.equals(entity.getInvalid()), "还未到作废时间，不能删除");
        giftActivityMapper.deleteById(entity);
        return true;
    }

    @Override
    public boolean update(AdminGiftActivitySaveDTO param) {
        GiftActivity entity = validateExists(param.getId());
        Assertions.isFalse(Boolean.TRUE.equals(entity.getInvalid()), "已到作废时间，不能修改");
        GiftActivity updateObj = convertToEntity(param);
        updateObj.setId(entity.getId());
        giftActivityMapper.updateById(updateObj);
        return true;
    }

    @Nonnull
    @Override
    protected Map<Long, ShopSimpleVO> getShopSimpleMap(Collection<Long> shopIds) {
        return shopInfoApi.getShopSimpleMap(shopIds);
    }

    @Override
    public List<GiftActivityVO> getAvailableListByShopId(Long shopId) {
        List<GiftActivity> giftActivities = giftActivityMapper.selectAvailableListByShopId(shopId, null);
        if (CollUtil.isEmpty(giftActivities)) {
            return List.of();
        }
        List<GiftActivityVO> list = giftActivities.stream().map(this::convertToViewObject).toList();
        Set<Long> shopIds = convertSet(list, GiftActivityVO::getShopId);
        Map<Long, ShopSimpleVO> shops = getShopSimpleMap(shopIds);
        for (GiftActivityVO vo : list) {
            vo.setShop(shops.getOrDefault(vo.getShopId(), ShopSimpleVO.EMPTY));
            RegionUtils.autoAssignCounty(RegionDataSet.ONLY_LATEST, vo.getShop().getCountyCode(), vo.getShop());
        }
        return list;
    }

}
